

using System;
using System.Data;
using System.IO;
using System.Linq;
using System.Linq.Dynamic;
using System.Linq.Expressions;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Abp.Linq;
using Abp.Linq.Extensions;
using Abp.Extensions;
using Abp.UI;
using Abp.Domain.Repositories;
using Abp.Domain.Services;

using Yozeev;
using Yozeev.BusinessLogic;
using Yozeev.Models;
using Yozeev.SystemConfig;
using Yozeev.UserManagerment.Users;
using Abp.Domain.Entities.Auditing;
using Yozeev.Help;

namespace Yozeev.BusinessLogic.DomainService
{
    /// <summary>
    /// Activity领域层的业务管理
    ///</summary>
    public class ActivityManager : CommonDomainService, IActivityManager
    {
		
		private readonly IRepository<Activity,Guid> _repository;
        private readonly IRepository<BranchUser, Guid> _branchUserRepository;
		private readonly IRepository<Customer, Guid> _customerRepository;
		private readonly IRepository<ActivityDetail, Guid> _activityDetailRepository;
        private readonly IRepository<Ticket, Guid> _ticketRepository;
        private readonly IRepository<ActivityTemp, Guid> _activityTempRepository;
        private readonly IRepository<Schedule, Guid> _scheduleRepository;

        /// <summary>
        /// Activity的构造方法
        ///</summary>
        public ActivityManager(
			IRepository<Activity, Guid> repository
			, IRepository<BranchUser, Guid> branchUserRepository
			, IRepository<Customer, Guid> customerRepository
			, IRepository<ActivityDetail, Guid> activityDetailRepository
			, IRepository<Ticket, Guid> ticketRepository
			, IRepository<TicketDetail, Guid> ticketDetailRepository
            , IRepository<ActivityTemp, Guid> activityTempRepository
            , IRepository<Schedule, Guid> scheduleRepository
        ) : base(branchUserRepository, customerRepository, ticketRepository, ticketDetailRepository)
		{
			_repository =  repository;
			_activityDetailRepository = activityDetailRepository;
            _activityTempRepository = activityTempRepository;
            _scheduleRepository = scheduleRepository;
        }


		/// <summary>
		/// 初始化
		///</summary>
		public void InitActivity()
		{
			throw new NotImplementedException();
		}

        // TODO:编写领域业务代码

        /// <summary>
        /// 设置取票码
        /// </summary>
        /// <param name="activityCode"></param>
        public async Task SetActivityCodeAsync(string activityId, string activityCode)
        {
            var datas = await _repository.GetAllListAsync(a => a.Id.ToString().Equals(activityId));
            var activity = datas.FirstOrDefault();
            activity.Code = activityCode;
            await _repository.UpdateAsync(activity);
        }

        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="activity"></param>
        /// <returns></returns>
        public ActivityResultModel CreateActivity(Activity activity,ActivityTemp activityTemp=null) 
		{
			ActivityResultModel activityResult = new ActivityResultModel() 
			{ 
				ResultCode ="000",
				ResultMessage = "下单成功"
			};
            var TicketDetailIds = new List<Guid>();
			try
			{
				var customer = activity.ActivityDetails.FirstOrDefault().Customer;
				//var customer = GetCustomersById(customerId);
                var _activity = new Activity()
                {
                    Id = Guid.NewGuid(),
                    ActivityNo = CommonHelp.getVoucherNo(),
                    ActivityDate = DateTime.Today,
                    PlayDate = activity.PlayDate/*.ActivityDetails.FirstOrDefault().Schedule.SaleDate*/,
                    //CustomerId = customerId,
                    //Buyer = customer.CustomerName,
                    //Mobile = customer.Mobile,
                    IsPrint = false,
                    Closed = false,
                    Remark = activity.Remark,
                    PayMethodId = activity.PayMethodId,
                    SourceId = activity.SourceId,
                    OrderType = activity.OrderType,
                    TotalQuantity = activity.TotalQuantity,
                    TotalAmount = activity.TotalAmount,
                    ScheduleId = activity.ActivityDetails.FirstOrDefault().Schedule.Id,
                    PayStatus = PayStatusEnum.PayStatusPayment,
                    VoucherNo = activityTemp != null ? activityTemp.VoucherNo : CommonHelp.getVoucherNo(),
                };
                if(customer!=null)
                {
                    _activity.CustomerId = customer.Id;
                    _activity.Buyer = customer.CustomerName;
                    _activity.Mobile = customer.Mobile;
                }
                if (!activity.Remark.IsNullOrWhiteSpace())
                    _activity.Remark = activity.Remark;
                if (activity.OrderType == Abp.Domain.Entities.Auditing.OrderTypeEnum.OrderTypeTravelAgency)
                    _activity.TravelAgencyId = activity.TravelAgencyId;
				var createBranch = GetBranchUser((long)activity.CreatorUserId);
				CommonHelp.SetBranchId(_activity, createBranch);
				_repository.Insert(_activity);
				//遍历activityDetail
				activity.ActivityDetails.ToList().ForEach(activityDetail => {
					//获取票型
					var ticket = GetTicket(activityDetail.TicketPrice);
					//创建订单明细
					var _activityDetail = new ActivityDetail()
					{
                        Id = Guid.NewGuid(),
                        ActivityId = _activity.Id,
                        TicketPriceId = activityDetail.TicketPrice.Id,
                        UnitPrice = activityDetail.TicketPrice.Price,
                        Discount = activityDetail.TicketPrice.Discount,
                        SalePrice = activityDetail.TicketPrice.Price * activityDetail.TicketPrice.Discount,
                        TotalAmount = activityDetail.TicketPrice.Price * activityDetail.TicketPrice.Discount,
                        Quantity = activityDetail.Quantity,
                        ScheduleId = activityDetail.Schedule.Id,
                        WarePosition = activityDetail.TicketPrice.WarePosition,
                    };
					CommonHelp.SetBranchId(_activityDetail, createBranch);
					_activityDetailRepository.Insert(_activityDetail);
					//创建票据
					var ticketDetailId = Guid.NewGuid();
					var ticketDetail = new TicketDetail()
					{
						Id = ticketDetailId,
						TicketNo = CommonHelp.getVoucherNo(),
						ActivityDetailId = _activityDetail.Id,
						ActivityId = _activity.Id,
						CustomerId = activityDetail.Customer.Id,
						TicketId = activityDetail.TicketPrice.TicketId,
						QRCode = CommonHelp.getQRCode(ticketDetailId.ToString()),
						CheckingQuantity = 1,
						CheckedQuantity = 0,
						StartDateTime = activityDetail.Schedule.StartTime,
						EndDateTime = activityDetail.Schedule.EndTime,
						CheckMethod = ticket.CheckMethod,
						RouteId = activityDetail.Schedule.RouteId,
						ScheduleId = activityDetail.Schedule.Id,
						BoatId = activityDetail.Schedule.BoatId,
						TicketStatus = TicketStatusEnum.Activate,
                        WarePosition = activityDetail.TicketPrice.WarePosition,
					};
					CommonHelp.SetBranchId(ticketDetail, createBranch);
					_ticketDetailRepository.Insert(ticketDetail);
                    TicketDetailIds.Add(ticketDetailId);
                });
                if (activityTemp!=null)
                {
                    var _temp = _activityTempRepository.GetAsync(activityTemp.Id).Result;
                    _temp.PayStatus = PayStatusEnum.PayStatusPayment;
                    _temp.ActivityId = _activity.Id;
                    _temp.PayTime = DateTime.Now;
                    _temp.Collector = activity.CreatorUserId.ToString();
                    _activityTempRepository.Update(_temp);
                }
                //返回票据信息
                activityResult.Date = GetTicketForms(TicketDetailIds.ToArray());
                //返回订单Id
                activityResult.ActivityId = _activity.Id;
                return activityResult;
			}
			catch (Exception ex)
			{
				throw ex;
			}
		}
        /// <summary>
        /// 根据票据列表退费，每一个票据生成一个退款单
        /// </summary>
        /// <param name="ticketDetailList">票据列表</param>
        /// <param name="userId">操作人员ID</param>
        /// <param name="rDiscount">退费折扣</param>
        /// <returns></returns>
        public ActivityResultModel RefundActivity(List<TicketDetail> ticketDetailList,long userId,decimal rDiscount,string remark="")
        {
            ActivityResultModel activityResult = new ActivityResultModel()
            {
                ResultCode = "000",
                ResultMessage = "退票成功"
            };
            try
            {
                decimal rAmount = 0;
                ticketDetailList.ForEach(ticketDetail =>
                {
                    var activityDetail = ticketDetail.ActivityDetail;
                    var activity = activityDetail.Activity;
                    //创建退票订单
                    var ractivity = new Activity()
                    {
                        Id = Guid.NewGuid(),//退票单ID
                        OrgActivityId = activity.Id,//原订单ID
                        ActivityDate = DateTime.Now.Date,//订单生成日期
                        PayStatus = PayStatusEnum.PayStatusPayment,//支付状态(新订单初始状态是已付款，结账后为关闭，退款后为已退款)
                        TotalQuantity = 1,//数量取反
                        TotalAmount = -getRefundAmount((activityDetail.TotalAmount / activityDetail.Quantity) * rDiscount),
                        AccountsId = null,//结账ID置空
                        ActivityType = ActivityTypeEnum.ActivityTypeRefund,//单据类型为退款单
                        ActivityNo = CommonHelp.getVoucherNo(),
                        SourceId = activity.SourceId,
                        PlayDate = activity.PlayDate,
                        CustomerId = activity.CustomerId,
                        Buyer = activity.Buyer,
                        Mobile = activity.Mobile,
                        PayMethodId = activity.PayMethodId,
                        IsPrint = false,
                        Closed = false,
                        OrderType = activity.OrderType,
                        Remark = remark,
                        ScheduleId = activity.ScheduleId,
                    };
                    if (activity.TravelAgencyId != null)
                        ractivity.TravelAgencyId = activity.TravelAgencyId;
                    var createBranch = GetBranchUser(userId);
                    CommonHelp.SetBranchId(ractivity, createBranch);
                    _repository.Insert(ractivity);
                    rAmount = ractivity.TotalAmount;
                    //修改原订单
                    activity.PayStatus = PayStatusEnum.PayStatusRefund;//原订单修改支付状态
                    _repository.UpdateAsync(activity);
                    //创建退票订单明细
                    var UnitPrice = -getRefundAmount((activityDetail.TotalAmount / activityDetail.Quantity) * rDiscount);
                    var ractivityDetail = new ActivityDetail()
                    {
                        Id = Guid.NewGuid(),
                        Activity = null,
                        ActivityId = ractivity.Id,
                        Quantity = 1,
                        Discount = 1,
                        UnitPrice = -getRefundAmount((activityDetail.TotalAmount / activityDetail.Quantity) * rDiscount),
                        SalePrice = UnitPrice,
                        TotalAmount = UnitPrice,
                        AccountDetailId = null,
                        AccountId = null,
                        OrgDetailId = activityDetail.Id,
                        TicketPriceId = activityDetail.TicketPriceId,
                        Remark = remark,
                        ScheduleId = activityDetail.ScheduleId,
                    };
                    CommonHelp.SetBranchId(ractivityDetail, createBranch);
                    _activityDetailRepository.Insert(ractivityDetail);
                    //修改原票据状态
                    ticketDetail.OrgActivityDetailId = ractivityDetail.Id;
                    ticketDetail.OrgActivityId = ractivity.Id;
                    ticketDetail.TicketStatus = TicketStatusEnum.TicketRefund;
                    _ticketDetailRepository.Update(ticketDetail);
                });
                activityResult.Date = rAmount;
                
                return activityResult;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public List<Activity> GetActivityListByIds(Guid[] guids)
		{
			var query = _repository.GetAll();
			var entityList = query.Where(m => guids.Contains(m.Id)).ToList();
			return entityList;
		}
        /// <summary>
        /// 退费规则，超出小数部分进1
        /// </summary>
        /// <param name="amount"></param>
        /// <returns></returns>
        public decimal getRefundAmount(decimal amount)
        {
            return Math.Ceiling(amount);
        }
        private  List<ActivityDetail> GetActivityDetailByActivity(Guid ActivityId)
        {
            var list = _activityDetailRepository.GetAll();
            return list.Where(m => m.ActivityId == ActivityId).ToList();
        }
        public ActivityDetail GetActivityDetailById(Guid Id)
        {
            var list = _activityDetailRepository.GetAll();
            return list.FirstOrDefault(m => m.Id == Id);
        }
        public Activity GetActivityById(Guid Id)
        {
            var list = _repository.GetAll();
            return list.FirstOrDefault(m => m.Id == Id);
        }

        /// <summary>
        /// 根据支付凭证VoucherNo获取订单
        /// </summary>
        /// <param name="VoucherNo"></param>
        /// <returns></returns>
        public Activity GetActivityByVoucherNo(string VoucherNo)
        {
            var list = from activity in _repository.GetAll().AsNoTracking()
                       where activity.VoucherNo == VoucherNo
                       select new { activity, activity.Source, activity.PayMethod, activity.ActivityDetails }
                       ;
            var activityList = new List<Activity>();
            list.ToList().ForEach(t => {
                var Activity = t.activity;
                Activity.Source = t.Source;
                Activity.PayMethod = t.PayMethod;
                Activity.ActivityDetails = t.ActivityDetails;
                activityList.Add(Activity);
            });
            return activityList.FirstOrDefault();
        }

        public List<TicketForm> GetTicketForms(Guid[] TicketDetailIds)
        {
            var query = from ticketDetail in _ticketDetailRepository.GetAll().Where(m => TicketDetailIds.Contains(m.Id))
                        select new
                        {
                            ticketDetail,
                            ticketDetail.Schedule,
                            ticketDetail.Boat,
                            ticketDetail.Route,
                            ticketDetail.Customer,
                            ticketDetail.ActivityDetail,
                            ticketDetail.ActivityDetail.TicketPrice,
                            ticketDetail.ActivityDetail.TicketPrice.Ticket,
                        };
            var list = new List<TicketForm>();
            query.ToList().ForEach(temp => {
                list.Add(new TicketForm()
                {
                    TicketDetailId = temp.ticketDetail.Id,
                    BoatName = temp.Boat.BoatName,
                    PlayDate = temp.Schedule.SaleDate.ToString("yyyy-MM-dd"),
                    PlayTime = temp.Schedule.StartTime.ToString("HH:mm"),
                    CustomerName = temp.Customer.CustomerName,
                    QRCode = temp.ticketDetail.QRCode,
                    TicketNo = temp.ticketDetail.TicketNo,
                    TicketStatus = temp.ticketDetail.TicketStatus
                });
            });
            return list;
        }

        public async Task<Activity> GetEntity(Guid Id)
        {
            var entity = await _repository.GetAsync(Id);
            return entity;
        }
    }
}
